home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / macros / texsis / tables / TABLES.tex < prev    next >
Text File  |  1992-08-10  |  21KB  |  622 lines

  1. % +--------------------------------------------------------------------+
  2. % |                                                                    |
  3. % |                           TABLES.TEX                               |
  4. % |                                                                    |
  5. % |                     Ray F. Cowan  15-Feb-85                        |
  6. % |                                                                    |
  7. % |                       Princeton University                         |
  8. % |                                                                    |
  9. % |                     Last Revision: 17-Apr-86                       |
  10. % |                                                                    |
  11. % |   Macros I find handy for making tables.  See TABLEDOC TEX for     |
  12. % |   a longer description.  The token-counting macros are straight    |
  13. % |   from the TeXbook's "Dirty Tricks" appendix.                      |
  14. % |                                                                    |
  15. % +--------------------------------------------------------------------+
  16. %
  17. %     Modified for TeX 2.0 with CM fonts by F.E. Paige, 14 Aug. 1987
  18. %
  19. %
  20. \newbox\hdbox%
  21. \newcount\hdrows%
  22. \newcount\multispancount%
  23. \newcount\ncase%
  24. \newcount\ncols% This is the number of primary text columns in the table.
  25. \newcount\nrows%
  26. \newcount\nspan%
  27. \newcount\ntemp%
  28. \newdimen\hdsize%
  29. \newdimen\newhdsize%
  30. \newdimen\parasize%
  31. \newdimen\spreadwidth%
  32. \newdimen\thicksize%
  33. \newdimen\thinsize%
  34. \newdimen\tablewidth%
  35. \newif\ifcentertables%
  36. \newif\ifendsize%
  37. \newif\iffirstrow%
  38. \newif\iftableinfo%
  39. \newtoks\dbt%
  40. \newtoks\hdtks%
  41. \newtoks\savetks%
  42. \newtoks\tableLETtokens%
  43. \newtoks\tabletokens%
  44. \newtoks\widthspec%
  45. %
  46. %  Book-keeping stuff--see how often these macros are called.
  47. %
  48. %FEP:      CP SMSG removed - FOR IBM
  49. %FEP: \immediate\write15{%
  50. %FEP: CP SMSG GJMSINK TEXTABLE --> TABLE MACROS V. 851121 JOB = \jobname%
  51. %FEP: }%
  52. %
  53. %  Turn on table diagnostics.
  54. %
  55. \tableinfotrue%
  56. \catcode`\@=11%  Allows use of "@" in macro names, like PLAIN.TEX does.
  57. \def\out#1{\immediate\write16{#1}}%  Debugging aid.  Writes #1 on the
  58. %                                    user's terminal and in the log file.
  59. %
  60. %  Define the \tstrut height, depth in terms of the x_height parameter.
  61. %
  62. \def\tstrut{\vrule height3.1ex depth1.2ex width0pt}%
  63. \def\and{\char`\&}%  Allows us to get an `&' in the text.  This is the
  64. %                    same as using the PLAIN TeX macro \&.
  65. \def\tablerule{\noalign{\hrule height\thinsize depth0pt}}%
  66. \thicksize=1.5pt%  Default thickness for fat rules.  The user should feel
  67. %                  free to change this to his preference.
  68. \thinsize=0.6pt%   Default thickness for thin rules.
  69. \def\thickrule{\noalign{\hrule height\thicksize depth0pt}}%
  70. \def\hrulefill{\leaders\hrule\hfill}%
  71. \def\bigrulefill{\leaders\hrule height\thicksize depth0pt \hfill}%
  72. \def\ctr#1{\hfil\ #1\hfil}%
  73. \def\altctr#1{\hfil #1\hfil}%
  74. \def\vctr#1{\hfil\vbox to0pt{\vss\hbox{#1}\vss}\hfil}%
  75. %
  76. %  Here are things for controlling the width of the finished table.
  77. %
  78. \tablewidth=-\maxdimen%
  79. \spreadwidth=-\maxdimen%
  80. \def\tabskipglue{0pt plus 1fil minus 1fil}%
  81. %
  82. %  Stuff for centering or not.
  83. %
  84. \centertablestrue%
  85. \def\centeredtables{%
  86.    \centertablestrue%
  87. }%
  88. \def\noncenteredtables{%
  89.    \centertablesfalse%
  90. }%
  91. %
  92. %  \vctr vertically centers its argument in the row.
  93. %
  94. \parasize=4in%
  95. \long\def\para#1{%  Used to make little paragraphs out of one entry.
  96.    {%
  97.       \vtop{%
  98.          \hsize=\parasize%
  99.          \baselineskip14pt%
  100.          \lineskip1pt%
  101.          \lineskiplimit1pt%
  102.          \noindent #1%
  103.          \vrule width0pt depth6pt%
  104.       }%
  105.    }%
  106. }%
  107. %
  108. \gdef\ARGS{########}%  Produces the correct number of #'s in the preamble
  109. %                      by the time eveything is expanded and \halign sees
  110. %                      it.
  111. \gdef\headerARGS{####}%  Same as \ARGS, but used in \header macros.
  112. \def\@mpersand{&}%  Allows us to get alignment tab characters later
  113. %                   when we have made the character "&" an active macro.
  114. {\catcode`\|=13%  Make |'s locally active.
  115. \gdef\letbarzero{\let|0}%  Globally define a macro that allows us to
  116. %                          keep active |'s from being expanded in edef's.
  117. \gdef\letbartab{\def|{&&}}%
  118. \gdef\letvbbar{\let\vb|}%
  119. %  This \def will cause active |'s read by
  120. %                            \ruledtable to be converted into double
  121. %                            alignment tabs.
  122. }%  End of locally active |'s.
  123. %
  124. {\catcode`\&=4%  Make these alignment tabs.
  125. \def\ampskip{&\omit\hfil&}%  This local macro skips a vertical rule.
  126. \catcode`\&=13%  Now make &'s into active macros.
  127. \let&0%  This allows us to expand \ampskip in the next \xdef without
  128. %        attempting to expand the & and getting an "undefined control
  129. %        sequence" error.
  130. \xdef\letampskip{\def&{\ampskip}}%
  131. \gdef\letnovbamp{\let\novb&\let\tab&}
  132. %  This will cause active &'s read by
  133. %                                   \ruledtable to be converted into
  134. %                                   double tabs and an \omit'ted \vrule.
  135. }%  End of locally active &'s.
  136. %
  137. \def\begintable{%  Here we make |'s and &'s active characters so we can
  138. %                  interpret them as macros.  Note that this action is
  139. %                  true only until we encounter the matching \endgroup
  140. %                  token later at the end of the \ruledtable macro.
  141.    \begingroup%
  142.    \catcode`\|=13\letbartab\letvbbar%
  143.    \catcode`\&=13\letampskip\letnovbamp%
  144.    \def\multispan##1{%  We must redefine \multispan to count the number
  145. %                       of primary columns, not physical columns.
  146.       \omit \mscount##1%
  147.       \multiply\mscount\tw@\advance\mscount\m@ne%
  148.       \loop\ifnum\mscount>\@ne \sp@n\repeat%
  149.    }%  End of \multispan macro.
  150.    \def\|{%
  151.       &\omit\widevline&%
  152.    }%
  153.    \ruledtable%  Now we call \ruledtable to do the real work.
  154. }%  End of \begintable macro.
  155. %
  156. \long\def\ruledtable#1\endtable{%
  157. %
  158. %  This macro reads in the user's data entries
  159. %  and converts them into a ruled table.
  160. %
  161. %  Important note:  Many macros and parameters are re-defined here, and
  162. %  these must be kept local to the table macros to avoid conflict with
  163. %  their use outside of tables.  This is done by the \begingroup token
  164. %  macro \begintable and the \endgroup token at the end of
  165. %  this macro.
  166. %
  167.    \offinterlineskip%  Needed to make rules touch each other.
  168.    \tabskip 0pt%  Needed for same reason as \offinterlineskip.
  169.    \def\widevline{\vrule width\thicksize}%  Make outer \vrule's wider.
  170.    \def\endrow{\@mpersand\omit\hfil\crnorm\@mpersand}%
  171.    \def\crthick{\@mpersand\crnorm\thickrule\@mpersand}%
  172.    \def\crthickneg##1{\@mpersand\crnorm\thickrule
  173.           \noalign{{\skip0=##1\vskip-\skip0}}\@mpersand}%
  174.    \def\crnorule{\@mpersand\crnorm\@mpersand}%
  175.    \def\crnoruleneg##1{\@mpersand\crnorm
  176.           \noalign{{\skip0=##1\vskip-\skip0}}\@mpersand}%
  177.    \let\nr=\crnorule%  A shorter abbreviation.
  178.    \def\endtable{\@mpersand\crnorm\thickrule}%
  179. %
  180.    \let\crnorm=\cr%  Allows us to use \cr for our own purposes.
  181. %
  182. %  Cause user-typed \cr's to follow a row with a \tablerule.
  183. %
  184.    \edef\cr{\@mpersand\crnorm\tablerule\@mpersand}%
  185.    \def\crneg##1{\@mpersand\crnorm\tablerule
  186.           \noalign{{\skip0=##1\vskip-\skip0}}\@mpersand}%
  187.    \let\ctneg=\crthickneg
  188.    \let\nrneg=\crnoruleneg
  189. %
  190.    \the\tableLETtokens%  Get the user's extra \let's, if any.
  191. %
  192. %  Put the data entries into a token register so we can scan through them
  193. %  and see what the user is asking us to do.
  194. %
  195.    \tabletokens={}%  We add an extra alignment tab to the beginning
  196. %                       of the first row to allow for the first \vrule.
  197. %
  198. %  Now count how many rows are in the table and return the result in
  199. %  count register \nrows; do the same for columns, and return that
  200. %  in register \ncols.
  201. %
  202.    \countROWS\tabletokens\into\nrows%
  203.    \countCOLS\tabletokens\into\ncols%
  204. %
  205. %  Now do a little arithmetic to convert the number of primary columns
  206. %  into the number of physical columns that the alignment preamble must
  207. %  prepare for;  similarly for rows.
  208. %
  209.    \advance\ncols by -1%
  210.    \divide\ncols by 2%
  211.    \advance\nrows by 1%
  212. %
  213. %  Tell the user how many rows and columns we found in his data, if he
  214. %  wants to know.
  215. %
  216.    \iftableinfo %
  217.       \immediate\write16{[Nrows=\the\nrows, Ncols=\the\ncols]}%
  218.    \fi%
  219. %
  220. %  Now we actually go ahead and produce the table.
  221. %
  222.    \ifcentertables
  223.       \ifhmode \par\fi%  Make sure we are in vertical mode.
  224.       \line{%  The final table comes out as an \hbox of width the \hsize.
  225.       \hss%  The final table will be centered left-to-right.
  226.    \else %
  227.       \hbox{%
  228.    \fi
  229.       \vbox{%
  230.          \makePREAMBLE{\the\ncols}%  Generate the preamble.
  231.          \edef\next{\preamble}%  This line and the next line force the
  232.          \let\preamble=\next%    expansion of all \ARGS tokens into the
  233. %                                appropriate number of #'s.
  234.          \makeTABLE{\preamble}{\tabletokens}%  Go do the \halign here.
  235.       }%  End of \vbox.
  236.       \ifcentertables \hss}\else }\fi%  Finish the centering effect.
  237. %                                       It is important that no spaces
  238. %                                       follow the two `}' here.
  239. %  }%  End of \line.
  240.    \endgroup%  Return all local macros and parameters to their outside
  241. %              values.
  242.    \tablewidth=-\maxdimen%  Reset \tablewidth to normal.
  243.    \spreadwidth=-\maxdimen% Same for \spreadwidth.
  244. }%  End of macro \ruledtable.
  245. %
  246. \def\makeTABLE#1#2{%  Does an \halign for the \ruledtable macro.
  247.    {%  Start of local parameter values.
  248. %
  249.    \let\ifmath0%     These macros would cause trouble if they were to be
  250.    \let\header0%     expanded in the following \xdef; we \let them be
  251.    \let\multispan0%  equal to a digit, because digits can't be expanded.
  252. %
  253. %  Set up the width specification here.
  254. %
  255.    \ncase=0%
  256.    \ifdim\tablewidth>-\maxdimen \ncase=1\fi%
  257.    \ifdim\spreadwidth>-\maxdimen \ncase=2\fi%
  258.    \relax%  This \relax is absolutely necessary, without it the following
  259. %           \ifcase will always take \ncase=0.
  260. %
  261.    \ifcase\ncase %
  262.       \widthspec={}%
  263.    \or %
  264.       \widthspec=\expandafter{\expandafter t\expandafter o%
  265.                  \the\tablewidth}%
  266.    \else %
  267.       \widthspec=\expandafter{\expandafter s\expandafter p\expandafter r%
  268.                  \expandafter e\expandafter a\expandafter d%
  269.                  \the\spreadwidth}%
  270.    \fi %
  271. %\out{Widthspec=[\the\widthspec]}%
  272. %\out{Preamble=[\preamble]}%
  273.    \xdef\next{%  We must force the preamble to be expanded BEFORE the
  274.       \halign\the\widthspec{%
  275. %        \halign is done;  this \edef\next{...}\next construction
  276. %                does the trick.
  277.       #1%  This is the preamble text.
  278. %
  279.       \noalign{\hrule height\thicksize depth0pt}%  Makes the top \hrule.
  280. %
  281.       \the#2\endtable%  This is the main body.
  282. %
  283. %     \noalign{\hrule height0.7pt depth0pt}%  Makes the last \hrule.
  284.       }%  End of \halign.
  285.    }%  End of \next.
  286.    }%  End of local values.
  287.    \next%  This \next must be outside of the local values, because now
  288. %          we want those troublesome macros in the \let's above to have
  289. %          their normal actions.
  290. }%  End of macro \makeTABLE.
  291. %
  292. \def\makePREAMBLE#1{%  This macro generates the necessary preamble for a
  293. %                      ruled table with #1 primary columns.
  294. %                      (Primary columns means the number of columns NOT
  295. %                       counting those used for vertical rules.)
  296.    \ncols=#1%  Get the number of columns desired.
  297.    \begingroup%  Start local parameter definitions.
  298.    \let\ARGS=0%  This is the key to the whole thing; it prevents \ARGS
  299. %                from being expanded in the following \edef's.
  300.    \edef\xtp{\widevline\ARGS\tabskip\tabskipglue%
  301.    &\ctr{\ARGS}\tstrut}%  A 1-column preamble.  Gets the sizing right.
  302.    \advance\ncols by -1%  One column has been generated; decrement the
  303. %                         counter.
  304.    \loop%  Append as many further columns as needed to the preamble.
  305.       \ifnum\ncols>0 %
  306.       \advance\ncols by -1%
  307.       \edef\xtp{\xtp&\vrule width\thinsize\ARGS&\ctr{\ARGS}}%
  308.    \repeat
  309.    \xdef\preamble{\xtp&\widevline\ARGS\tabskip0pt%
  310.    \crnorm}%  Adds the last \vrule.
  311.    \endgroup%  End of local parameters.
  312. }%  End of macro \makePREAMBLE.
  313. %
  314. \def\countROWS#1\into#2{%  This counts the number of rows in #1 by
  315. %                          looking for control sequences that end a row,
  316. %                          e.g., \cr, \crthick, etc., and puts the result
  317. %                          into count register #2.
  318.    \let\countREGISTER=#2%
  319.    \countREGISTER=0%
  320. %  \out{In countROWS:  tokens are [\the#1]}%
  321.    \expandafter\ROWcount\the#1\endcount%
  322. }%
  323. %
  324. \def\ROWcount{%
  325.    \afterassignment\subROWcount\let\next= %
  326. }%
  327. \def\subROWcount{%
  328. %  \out{In subROWcount:  next is [\meaning\next]}%  Debugging aid.
  329.    \ifx\next\endcount %
  330.       \let\next=\relax%
  331.    \else%
  332.       \ncase=0%
  333.       \ifx\next\cr %
  334.          \global\advance\countREGISTER by 1%
  335.          \ncase=0%
  336.       \fi%
  337.       \ifx\next\endrow %
  338.          \global\advance\countREGISTER by 1%
  339.          \ncase=0%
  340.       \fi%
  341.       \ifx\next\crthick %
  342.          \global\advance\countREGISTER by 1%
  343.          \ncase=0%
  344.       \fi%
  345.       \ifx\next\crnorule %
  346.          \global\advance\countREGISTER by 1%
  347.          \ncase=0%
  348.       \fi%
  349.       \ifx\next\crthickneg %
  350.          \global\advance\countREGISTER by 1%
  351.          \ncase=0%
  352.       \fi%
  353.       \ifx\next\crnoruleneg %
  354.          \global\advance\countREGISTER by 1%
  355.          \ncase=0%
  356.       \fi%
  357.       \ifx\next\crneg %
  358.          \global\advance\countREGISTER by 1%
  359.          \ncase=0%
  360.       \fi%
  361.       \ifx\next\header %
  362. %     \out{In subROWcount:  next=header, ncase set=1}%
  363.          \ncase=1%
  364.       \fi%
  365. %     \out{In subROWcount:  ncase is [\the\ncase]}%
  366.       \relax%
  367.       \ifcase\ncase %
  368.          \let\next\ROWcount%
  369. %        \out{subROWcount---> ncase=\the\ncase}%
  370.       \or %
  371.          \let\next\argROWskip%
  372. %        \out{subROWcount---> ncase=\the\ncase}%
  373.       \else %
  374.       \fi%
  375.    \fi%
  376. %  \out{subROWcount---> NEXT=\meaning\next}%
  377.    \next%
  378. }%  End of macro \subROWcount.
  379. %
  380. \def\counthdROWS#1\into#2{%
  381. \dvr{10}%
  382.    \let\countREGISTER=#2%
  383.    \countREGISTER=0%
  384. \dvr{11}%
  385. %  \out{In counthdROWS:  tokens are [\the#1]}%
  386. \dvr{13}%
  387.    \expandafter\hdROWcount\the#1\endcount%
  388. \dvr{12}%
  389. }%
  390. %
  391. \def\hdROWcount{%
  392.    \afterassignment\subhdROWcount\let\next= %
  393. }%
  394. \def\subhdROWcount{%
  395. %\out{In subhdROWcount:  next is [\meaning\next]}%
  396.    \ifx\next\endcount %
  397.       \let\next=\relax%
  398.    \else%
  399.       \ncase=0%
  400.       \ifx\next\cr %
  401.          \global\advance\countREGISTER by 1%
  402.          \ncase=0%
  403.       \fi%
  404.       \ifx\next\endrow %
  405.          \global\advance\countREGISTER by 1%
  406.          \ncase=0%
  407.       \fi%
  408.       \ifx\next\crthick %
  409.          \global\advance\countREGISTER by 1%
  410.          \ncase=0%
  411.       \fi%
  412.       \ifx\next\crnorule %
  413.          \global\advance\countREGISTER by 1%
  414.          \ncase=0%
  415.       \fi%
  416.       \ifx\next\header %
  417. %\out{In subhdROWcount:  next=header, ncase set=1}%
  418.          \ncase=1%
  419.       \fi%
  420. %\out{In subhdROWcount:  ncase is [\the\ncase]}%
  421. \relax%
  422.       \ifcase\ncase %
  423.          \let\next\hdROWcount%
  424. %\out{subhdROWcount---> ncase=\the\ncase}%
  425.       \or%
  426.          \let\next\arghdROWskip%
  427. %\out{subhdROWcount---> ncase=\the\ncase}%
  428.       \else %
  429.       \fi%
  430.    \fi%
  431. %\out{subhdROWcount---> NEXT=\meaning\next}%
  432.    \next%
  433. }%
  434. %
  435. {\catcode`\|=13\letbartab
  436. \gdef\countCOLS#1\into#2{%
  437. %  \out{In countCOLS:  tokens are [\the#1]}
  438.    \let\countREGISTER=#2%
  439.    \global\countREGISTER=0%
  440.    \global\multispancount=0%
  441.    \global\firstrowtrue
  442.    \expandafter\COLcount\the#1\endcount%
  443.    \global\advance\countREGISTER by 3%
  444.    \global\advance\countREGISTER by -\multispancount
  445. %  \out{countCOLS-->[\the\countREGISTER]}
  446. }%
  447. %
  448. \gdef\COLcount{%
  449.    \afterassignment\subCOLcount\let\next= %
  450. }%
  451. {\catcode`\&=13%
  452. \gdef\subCOLcount{%
  453. %\out{In subCOLcount: next is [\meaning\next]}
  454.    \ifx\next\endcount %
  455.       \let\next=\relax%
  456.    \else%
  457.       \ncase=0%
  458.       \iffirstrow
  459.          \ifx\next& %
  460.             \global\advance\countREGISTER by 2%
  461.             \ncase=0%
  462.          \fi%
  463.          \ifx\next\span %
  464.             \global\advance\countREGISTER by 1%
  465.             \ncase=0%
  466.          \fi%
  467.          \ifx\next| %
  468.             \global\advance\countREGISTER by 2%
  469.             \ncase=0%
  470.          \fi
  471.          \ifx\next\|
  472.             \global\advance\countREGISTER by 2%
  473.             \ncase=0%
  474.          \fi
  475.          \ifx\next\multispan
  476.             \ncase=1%
  477.             \global\advance\multispancount by 1%
  478.          \fi
  479.          \ifx\next\header
  480.             \ncase=2%
  481.          \fi
  482.          \ifx\next\cr       \global\firstrowfalse \fi
  483.          \ifx\next\endrow   \global\firstrowfalse \fi
  484.          \ifx\next\crthick  \global\firstrowfalse \fi
  485.          \ifx\next\crnorule \global\firstrowfalse \fi
  486.          \ifx\next\crnoruleneg \global\firstrowfalse \fi
  487.          \ifx\next\crthickneg  \global\firstrowfalse \fi
  488.          \ifx\next\crneg       \global\firstrowfalse \fi
  489.       \fi%  End of \iffirstrow.
  490. \relax%\out{subCOL-->  ncase=[\the\ncase]}
  491. % \out{subCOL-->  next=\meaning\next}
  492.       \ifcase\ncase %
  493.          \let\next\COLcount%
  494.       \or %
  495.          \let\next\spancount%
  496.       \or %
  497.          \let\next\argCOLskip%
  498.       \else %
  499.       \fi %
  500.    \fi%
  501. %  \out{subCOL-->  countREGISTER=[\the\countREGISTER]}
  502.    \next%
  503. }%
  504. \gdef\argROWskip#1{%
  505. %  Deletes the next balanced, undelimited argument from a
  506. %                 token list.
  507. % \out{---> Entering argROWskip <---}
  508. % \out{In argROWskip:  deleted arg is [#1]}%
  509.    \let\next\ROWcount \next%
  510. }%  End of macro \argskip.
  511. \gdef\arghdROWskip#1{%
  512. %  Deletes the next balanced, undelimited argument from a
  513. %                 token list.
  514. % \out{---> Entering arghdROWskip <---}
  515. % \out{In arghdROWskip:  deleted arg is [#1]}%
  516.    \let\next\ROWcount \next%
  517. }%  End of macro \arghdROWskip.
  518. \gdef\argCOLskip#1{%
  519. %  Deletes the next balanced, undelimited argument from a
  520. %                 token list.
  521. % \out{---> Entering argCOLskip <---}
  522. % \out{In argCOLskip:  deleted arg is [#1]}%
  523.    \let\next\COLcount \next%
  524. }%  End of macro \argskip.
  525. }%  End of active &'s.
  526. }%  End of active |'s.
  527. \def\spancount#1{%\out{spancount--->\meaning#1}
  528.    \nspan=#1\multiply\nspan by 2\advance\nspan by -1%
  529.    \global\advance \countREGISTER by \nspan
  530. %  \out{number spancount--->\the\nspan; \the\countREGISTER}
  531.    \let\next\COLcount \next}%
  532. %
  533. %\def\dvr#1{\vrule width 1.0pt depth 0pt height 12pt$_{#1}$}
  534. \def\dvr#1{\relax}%
  535. % \omit\hfil%
  536. % \parindent=0pt\hsize=1.1in\valign{%
  537. % \vfil#\vfil&\vfil#\vfil\cr\hfil\hbox{\ Added to\ }\hfil&%
  538. % \hfil\hbox{\ empty events\ }\hfil\cr}\hfil%
  539. \def\header#1{%
  540. \dvr{1}{\let\cr=\@mpersand%
  541. \hdtks={#1}%
  542. %\out{In header:  hdtks=[\the\hdtks]}%
  543. \counthdROWS\hdtks\into\hdrows%
  544. \advance\hdrows by 1%
  545. \ifnum\hdrows=0 \hdrows=1 \fi%
  546. %\out{In header:  Nhdrows=[\the\hdrows]}%
  547. \dvr{5}\makehdPREAMBLE{\the\hdrows}%
  548. %\out{In header:  headerpreamble=[\headerpreamble]}%
  549. \dvr{6}\getHDdimen{#1}%
  550. %\out{In header:  hdsize=[\the\hdsize]}%
  551. %\striplastCR{#1}%
  552. {\parindent=0pt\hsize=\hdsize{\let\ifmath0%
  553. \xdef\next{\valign{\headerpreamble #1\crnorm}}}\dvr{7}\next\dvr{8}%
  554. }%
  555. }\dvr{2}}%  End of macro \header.
  556. %\def\striplastCR#1\cr{\xdef\headerbody{#1}}%
  557. \def\makehdPREAMBLE#1{%This macro generates the necessary preamble for a
  558. \dvr{3}%
  559. %                      ruled table with \ncols primary columns.
  560. %                      (Primary columns means the number of columns NOT
  561. %                       counting those used for vertical rules.
  562. \hdrows=#1%  Get the number of columns desired.
  563. {%  Start local parameter definitions.
  564. \let\headerARGS=0%
  565. %  This is the key to the whole thing; it prevents \ARGS
  566. \let\cr=\crnorm%
  567. %                from being expanded in the followin \edef's.
  568. \edef\xtp{\vfil\hfil\hbox{\headerARGS}\hfil\vfil}%
  569. \advance\hdrows by -1%  One row has been generated; decrement the
  570. %                         counter.
  571. \loop%  Append as many further rows as needed to the preamble.
  572. \ifnum\hdrows>0%
  573. \advance\hdrows by -1%
  574. \edef\xtp{\xtp&\vfil\hfil\hbox{\headerARGS}\hfil\vfil}%
  575. \repeat%
  576. \xdef\headerpreamble{\xtp\crcr}%
  577. }%  End of local parameters.
  578. \dvr{4}}%  End of \makehdPREAMBLE.
  579. %
  580. \def\getHDdimen#1{%
  581. %\out{In getHDdimen:  Arg 1=[#1]}%
  582. \hdsize=0pt%
  583. \getsize#1\cr\end\cr%
  584. }%  End of macro getHDdimen.
  585. \def\getsize#1\cr{%
  586. %\out{In getsize:  Arg 1=[#1]}%
  587. %  Here we have to check arg#1 and see if the first token in #1 is an
  588. %    \end; if so, we stop, else we check the width of arg#1.
  589. %  We recall that each arg#1 will be terminated with a \cr token.
  590. \endsizefalse\savetks={#1}%
  591. %\out{In getsize:  the savetks = [\the\savetks]}%
  592. \expandafter\lookend\the\savetks\cr%
  593. %\out{In getsize:  ifendsize = [\meaning\ifendsize]}%
  594. \relax \ifendsize \let\next\relax \else%
  595. \setbox\hdbox=\hbox{#1}\newhdsize=1.0\wd\hdbox%
  596. \ifdim\newhdsize>\hdsize \hdsize=\newhdsize \fi%
  597. %\out{In getsize:  hdsize=[\the\hdsize]}%
  598. %\out{In getsize:  newhdsize=[\the\newhdsize]}%
  599. \let\next\getsize \fi%
  600. \next%
  601. }%
  602. \def\lookend{\afterassignment\sublookend\let\looknext= }%
  603. \def\sublookend{\relax%
  604. %\out{In sublookend:  looknext = [\looknext]}%
  605. \ifx\looknext\cr %
  606. %\out{In sublooknext:  looknext=cr}%
  607. \let\looknext\relax \else %
  608. %\out{In sublooknext:  looknext/=cr}%
  609.    \relax
  610.    \ifx\looknext\end \global\endsizetrue \fi%
  611.    \let\looknext=\lookend%
  612.     \fi \looknext%
  613. }%
  614. %
  615. %  Allow the user to make his own names for crthick, etc.
  616. %
  617. \def\tablelet#1{%
  618.    \tableLETtokens=\expandafter{\the\tableLETtokens #1}%
  619. }%
  620. \catcode`\@=12%  Change @'s back to their normal category code.
  621. %
  622.